# +----------------------------------------------------------------------
# | zhanshop-app / appclient.py    [ 2024/3/16 09:31 ]
# +----------------------------------------------------------------------
# | Copyright (c) 2011~2025 zhangqiquan All rights reserved.
# +----------------------------------------------------------------------
# | Author: Administrator <768617998@qq.com>
# +----------------------------------------------------------------------
import time
from typing import List

from appium.options.android import UiAutomator2Options
from appium.webdriver import WebElement

from appium import webdriver
from selenium.webdriver.common.by import By

from zhanshop.app import App
from zhanshop.appium.element import Element
from zhanshop.env import Env


class Appclient():
    serverUrl = None
    capabilities = None
    driver = None
    elementTimeout = 3
    def __init__(self, capabilities: dict, serverUrl = None):
        """
        初始化appium连接
        :param capabilities:
        :param serverUrl:
        """
        if (serverUrl == None):
            self.serverUrl = App.make(Env).get("service.appium_host", "http://127.0.0.1:4723")
        else:
            self.serverUrl = serverUrl
        self.capabilities = capabilities
        self.driver = webdriver.Remote(self.serverUrl, options=UiAutomator2Options().load_capabilities(self.capabilities))

    def closeUsbPop(self):
        if("USB" in self.driver.page_source and "仅限充电" in self.driver.page_source and "传输文件" in self.driver.page_source and "传输照片" in self.driver.page_source):
            try:
                self.driver.find_element(By.XPATH, '//android.widget.LinearLayout[@resource-id="miui:id/buttonGroup"]').click()
            except Exception as e:
                pass

    def getElementById(self, name) -> WebElement:
        """
        通过 id 查找 HTML 元素
        :param idName:
        :return:
        """
        startTime = time.time()
        while True:
            try:
                element = self.driver.find_element(By.ID, name)
                break
            except Exception:
                element = None
            time.sleep(0.3)
            if (time.time() - startTime > self.elementTimeout): break
        return element

    def getElementsByClassName(self, name)->List[Element]:
        """
        通过 classname 查找 HTML 元素
        :param name:
        :return:
        """
        startTime = time.time()
        while True:
            try:
                elements = self.driver.find_element(By.CLASS_NAME, name)
                break
            except Exception:
                elements = []
            time.sleep(0.3)
            if (time.time() - startTime > self.elementTimeout): break
        if (len(elements) != 0):
            elementList = []
            for element in elements:
                element = Element(element)
                elementList.append(element)
            elements = elementList
        return elements

    def getElementXpath(self, path, slideTest = True) -> Element:
        """
        通过 id 查找 HTML 元素
        :param idName:
        :return:
        """
        startTime = time.time()
        while True:
            try:
                element = self.driver.find_element(By.XPATH, path)
                break
            except Exception:
                element = None
            time.sleep(0.3)
            if (time.time() - startTime > self.elementTimeout): break
        if(element != None):
            return Element(element)
        if(element == None and slideTest == True):
            screen_size = self.driver.get_window_size()
            y1 = screen_size['height'] * 0.4  # 起始Y坐标（例如屏幕的80%位置）
            y2 = screen_size['height'] * 0.1  # 结束Y坐标（例如屏幕的20%位置）
            self.swipe(0, y1, 0, y2, 0)
            return self.getElementXpath(path, False)
        return element
    def swipe(self, start_x, start_y, end_x, end_y, duration = 0):
        """
        滑动屏幕
        :param start_x:
        :param start_y:
        :param end_x:
        :param end_y:
        :param duration:
        :return:
        """
        self.driver.swipe(start_x, start_y, end_x, end_y, duration)

    def tap(self, positions, duration = 0):
        self.driver.tap(positions, duration)
    def back(self):
        """
        返回上一页
        :return:
        """
        self.driver.back()
    def pageSource(self):
        """
        获取页面全部数据
        :return:
        """
        return self.driver.page_source
    def close(self):
        """
        退出当前APP
        :return:
        """
        if(self.capabilities.get("appium:appPackage") != None):
            return self.driver.terminate_app(self.capabilities["appium:appPackage"])
    def quit(self):
        """
        退出当前会话
        :return:
        """
        return self.driver.quit()

    def execute_script(self, command):
        """
        执行脚本
        @param command:
        @return:
        """
        return self.driver.execute_script('mobile: shell', {'command': command})
